1 module collie.codec.http.httpwritebuffer; 2 3 import kiss.container.ByteBuffer; 4 import kiss.net; 5 import kiss.event.core; 6 import kiss.event.task; 7 8 @trusted abstract class HttpWriteBuffer : StreamWriteBuffer, WriteBuffer 9 { 10 override abstract size_t write(in ubyte[] data); 11 12 override abstract size_t set(size_t pos, in ubyte[] data); 13 14 override abstract @property size_t length() const; 15 16 void setFinalTask(AbstractTask task){ 17 _task = task; 18 } 19 20 override void doFinish() nothrow{ 21 if(_task !is null) 22 _task.job(); 23 } 24 StreamWriteBuffer next(){ return _next; } 25 void next(StreamWriteBuffer v) { _next = v; } 26 27 private: 28 StreamWriteBuffer _next; 29 AbstractTask _task; 30 } 31 32 class HTTPByteBuffer(Alloc) : HttpWriteBuffer 33 { 34 import kiss.container.ByteBuffer; 35 import kiss.container.Vector; 36 import std.experimental.allocator.common; 37 38 alias BufferStore = Vector!(ubyte,Alloc); 39 40 static if (stateSize!(Alloc) != 0) 41 { 42 this(Alloc alloc) 43 { 44 _store = BufferStore(1024,alloc); 45 } 46 47 @property allocator(){return _store.allocator;} 48 49 } else { 50 this() 51 { 52 _store = BufferStore(1024); 53 } 54 } 55 56 ~this(){ 57 destroy(_store); 58 } 59 60 override size_t write(in ubyte[] data) 61 { 62 size_t len = _store.length; 63 ()@trusted{_store.insertBack(cast(ubyte[])data);}(); 64 return _store.length - len; 65 } 66 67 override size_t set(size_t pos, in ubyte[] data) 68 { 69 import core.stdc.string : memcpy; 70 if(pos >= _store.length || data.length == 0) return 0; 71 size_t len = _store.length - pos; 72 len = len > data.length ? data.length : len; 73 ()@trusted{ 74 ubyte * ptr = cast(ubyte *)(_store.ptr + pos); 75 memcpy(ptr, data.ptr, len); 76 }(); 77 78 return len; 79 } 80 81 void rest(size_t size){ 82 _rsize = size; 83 } 84 85 const(ubyte)[] sendData() 86 { 87 size_t len = _rsize + 4096;// 一次最大发送4K 88 len = _store.length < len ? _store.length : len; 89 auto _data = _store.data(); 90 return _data[_rsize .. len]; 91 } 92 93 bool popSize(size_t size) 94 { 95 _rsize += size; 96 return _rsize >= _store.length; 97 } 98 99 override void doFinish() { 100 _store.clear(); 101 super.doFinish(); 102 } 103 104 override size_t length() const{ 105 return _store.length; 106 } 107 private: 108 BufferStore _store; 109 size_t _rsize = 0; 110 }